package framework;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import framework.advs.BaseAdvertisment;
import framework.portals.IrrTutBy;
import framework.portals.NeagentBy;
import webdriver.BaseForm;
import webdriver.CommonFunctions;

/**
 * Базовый класс для форм
 */
public class BaseFormExtended extends BaseForm{

	private static ArrayList<BaseAdvertisment>  resultList; // список объявлений
	private static BrowserExtended browserExt = new BrowserExtended();

	/**
	 * Геттер
	 * @return список объявлений
	 */
	public static ArrayList<BaseAdvertisment> getResultList() {
		return resultList;
	}
	/**
	 * Базовый конструктор
	 * @param locator - локатор
	 * @param formTitle - название формы
	 */
	protected BaseFormExtended(By locator, String formTitle) {
		super(locator, formTitle);
	}

	/**
	 * Считает число объявлений
	 * @param tableLocator - локатор таблицы для поиска
	 * @param rowLocator - локатор строки
	 * @return число результатов
	 */
	public Integer getResultsCount(String tableLocator, String rowLocator) {
		List<WebElement> list = browser.getDriver().findElementsByXPath(tableLocator+rowLocator);
		return list.size();
	}

	/**
	 * Находит текст объявлений и записывает в массив данных
	 * @param advLocator - локатор объявления
     * @param idLocator - локатор id
     * @param headerLocator - локатор заголовка
     * @param bodyLocator - локатор тела
     * @param portal - тип портала
	 * @return ArrayList найденных объявлений
	 */
	public ArrayList<BaseAdvertisment> getListOfAdvs(String advLocator, String idLocator, String headerLocator, String bodyLocator, Portal portal){
		ArrayList<BaseAdvertisment> resultsArrList = new ArrayList<BaseAdvertisment>();
		// находим все строки объявлений в таблице
		List<WebElement> list = browser.getDriver().findElements(By.xpath(advLocator));
		String id = null, header, body = "";
		int i = 0;
		for (WebElement el:list){
			switch (portal) {
			case IRR_TUT_BY:
				id = getId(el.findElement(By.xpath("."+idLocator)).getAttribute("href"));
				break;
			case NEAGENT_BY:
				id = el.getAttribute("id");
				break;
			default:
				break;
			}
			header = el.findElement(By.xpath("."+headerLocator)).getText();
			body = el.findElement(By.xpath("."+bodyLocator)).getText();
			resultsArrList.add(new BaseAdvertisment(id, header, body, null, null, null, null, true, null, null, null));
		//	i++;
		//	if (i>3) break;
		}
		return resultsArrList;
	}

	/**
	 * Выводит текст объявлений в консоль
	 * @param inputList - список объявлений
	 */
	public void printListResults(ArrayList<BaseAdvertisment> inputList){
		for (BaseAdvertisment adv: inputList){
			printItem(adv);
		}
	}

	/**
	 * Выводит текст 1 объявления в консоль
	 * @param adv - объявление
	 */
	public void printItem(BaseAdvertisment adv) {
		System.out.println();
		System.out.print("  ID: " +adv.getId());
		System.out.print("  >>> HEADER: " +adv.getHeader());
		System.out.print("  >>> BODY: " +adv.getBody());
	}

	/**
	 * Записывает телефоны объявлений в массив. Число телефонов зависит от портала: либо  телефоны всех объявлений на странице, либо только телефоны для одного объявления
	 * @param p - портал
	 * @param advBody - объявление
	 * @return phoneList
	 */
	public ArrayList<String> getAdvData(Portal p, String advBody) {
		ArrayList<String> returnList = new ArrayList<String>();
		WebElement body = browser.getDriver().findElement(By.xpath(advBody));
		int i = 0;
		switch (p) {

		case NEAGENT_BY:
			
			break;
			default: break;
		}
		return returnList;
		}

	/**
	 * Находит и заполняет параметры объявлений
	 * @param p - портал
	 * @param list - входной список объявлений
	 */
	public void collectAdvsData (ArrayList<BaseAdvertisment> list, Portal p){
		String s = "";
			switch (p) {
			case IRR_TUT_BY:
				for (BaseAdvertisment item: list){
				IrrTutBy irr = new IrrTutBy();
				s = item.getId();
				s = irr.linkToAdv(s);
				browser.navigate(s);

				ArrayList<String> irrTemp = irr.getPhones();
				item.setPhone1(irrTemp.get(0));
				if (irrTemp.size()>1){
				item.setPhone2(irrTemp.get(1));
				}

				irrTemp = irr.getRooms();
				item.setRooms(Integer.parseInt(irrTemp.get(0)));

				irrTemp = irr.getAgNames();
				item.setAgencyName(irrTemp.get(0));

				irrTemp = irr.getPrice();
				item.setPrice(Integer.parseInt(irrTemp.get(0).replace("$","").trim()));

				irrTemp = irr.getViews();
				item.setViews(Integer.parseInt(irrTemp.get(0)));

				irrTemp = irr.getCreationDate();
				item.setCreationDateTime(irrTemp.get(0) + "-T-"+getCurrentTime());

				}
				break;
			case NEAGENT_BY:
				NeagentBy neag = new NeagentBy();
				ArrayList<String> neagPhones  = neag.getPhones();
				ArrayList<String> neagRooms  = neag.getRooms();
				ArrayList<String> neagAgNames  = neag.getAgNames();
				ArrayList<String> neagPrice  = neag.getPrice();
				ArrayList<String> neagViews  = neag.getViews();
				ArrayList<String> neagCrDate  = neag.getCreationDate();
				Integer i = 0;
				for (BaseAdvertisment item: list){
					item.setPhone1(neagPhones.get(i));
					item.setPhone2("");
					item.setRooms(Integer.parseInt(neagRooms.get(i).substring(0, 1)));
					item.setAgencyName(neagAgNames.get(i));
					item.setPrice(Integer.parseInt(neagPrice.get(i).replace("$","").replace("€","").trim()));
					item.setViews(Integer.parseInt(neagViews.get(i)));
					item.setCreationDateTime(neagCrDate.get(i));
					i++;
				}
				break;
			default:
				break;
			}
		}

	/**
	 * Извлекает ИД из строки
	 * @param s - входная строка
	 * @return ИД
	 */
	private String getId(String s){
		String str = s.substring(s.lastIndexOf("/", s.length()-2) +1, s.length()-1);
		return str;
	}

	/**
	 * НА основе сравнения Ид списков проверяет, появились ли новые объявы
	 * @param oldList - первоначальный список
	 * @param newList - новый список
	 * @return появились ли новые объявы
	 */
	public boolean isNewAdvAppeared(ArrayList<BaseAdvertisment> oldList, ArrayList<BaseAdvertisment> newList){
		boolean isChanged = false;
		ArrayList<String> oldIdsList = getListIds(oldList);
		ArrayList<String> newIdsList = getListIds(newList);
		isChanged = !oldIdsList.containsAll(newIdsList);
		if (isChanged){
			newIdsList.removeAll(oldIdsList);
			resultList = retainNewAdvs(newList, newIdsList);
		}
		return isChanged;
	}

	/**
	 * Извлекает из списков ИД объявлений
	 * @param list - список
	 * @return ArrayList значений ИД
	 */
	private ArrayList<String> getListIds(ArrayList<BaseAdvertisment> list){
		ArrayList<String> idsList = new ArrayList<String>();
		for (BaseAdvertisment item:list){
			idsList.add(item.getId());
		}
		return idsList;
	}

	/**
	 * Находит и записывает названия агентств (подателей) объявлений в массив.
	 * Число записей зависит от портала: либо для всех объявлений на странице, либо только для одного
	 * @param p - портал
	 * @param advBody - объявление
	 * @param agNameLocator - локатор названия
	 * @return returnList
	 */
	public ArrayList<String> getAdvAgencyName(Portal p, String advBody, String agNameLocator) {
		ArrayList<String> returnList = new ArrayList<String>();
		WebElement body = browser.getDriver().findElement(By.xpath(advBody));
		int i = 0;
		switch (p) {

		case NEAGENT_BY:
			List<WebElement> nbody = browser.getDriver().findElements(By.xpath(advBody));
			for (WebElement el:nbody){
				WebElement l = el.findElement(By.xpath("."+agNameLocator));
				returnList.add(l.getText());
			}
			break;
			default: break;
		}
		return returnList;
		}

	/**
	 * Находит и записывает число комнат в массив.
	 * Число записей зависит от портала: либо для всех объявлений на странице, либо только для одного
	 * @param p - портал
	 * @param advBodyLocator - локатор объявления
	 * @param roomsNumLocator - локатор записи
	 * @return phoneList
	 */
	public ArrayList<String> getRoomsNumber(Portal p, String advBodyLocator, String roomsNumLocator) {
		ArrayList<String> returnList = new ArrayList<String>();
		WebElement body = browser.getDriver().findElement(By.xpath(advBodyLocator));
		int i = 0;
		switch (p) {
		case NEAGENT_BY:
			List<WebElement> nbody = browser.getDriver().findElements(By.xpath(advBodyLocator));
			for (WebElement el:nbody){
				WebElement l = el.findElement(By.xpath("."+roomsNumLocator));
				returnList.add(l.getText());
			}
			break;
			default: break;
		}
		return returnList;
		}

	/**
	 * Оставляет в новом списке только новые объявления
	 * @param inputList - список объявлений
	 * @param idsList - список ИДов
	 * @return ArrayList новых объявлений
	 */
	public ArrayList<BaseAdvertisment> retainNewAdvs(ArrayList<BaseAdvertisment> inputList, ArrayList<String> idsList){
		ArrayList<BaseAdvertisment> outputList = new ArrayList<BaseAdvertisment>();
		Iterator itr = idsList.iterator();
		for (BaseAdvertisment item: inputList){
			String id = item.getId();
			for (int i=0; i<idsList.size();i++){
				String targetId = idsList.get(i);
				if (id.equals(targetId)){
					info("id.equals" + id.equals(targetId));
					outputList.add(item);
				}
			}
		}
		return outputList;
	}
	/**
	 * Перечисление используемых порталов
	 */
	public enum Portal {
		IRR_TUT_BY("irr.tut.by"), NEAGENT_BY("neagent.by");
		private String value;
		/**
		 * Конструктор
		 * @param val - значение
		 */
		Portal(String val) {
			this.value = val;
		}
		/**
		 * Возвращает значение элемента
		 * @return значение
		 */
		public String toString() {
			return value;
		}
	}
	/**
	 * Возвращает текущее время
	 * @return ссылку
	 */
	public String getCurrentTime() {
		return CommonFunctions.getCurrentDate("HH:mm:ss");
	}
}
